import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.util.Scanner;

/**
 * 
 * @author Dennis Meyer, Sebastian Brodehl, Sebastian Schappert
 * @version 0.0.0.1
 *
 */
public class CurriculumVitae0
{
	private final String REGEXGERMANPHONENUMBER 
	= "^(((((((00|\\+)49[ \\-/]?)|0)[1-9][0-9]{1,4})[ \\-/]?)|((((00|\\+)49\\()|\\(0)[1-9][0-9]{1,4}\\)[ \\-/]?))[0-9]{1,7}([ \\-/]?[0-9]{1,5})?)$";
	
	private final String REGEXEMAIL
	= "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
	
	private final String FILEPATH = "/Users/Dennis/Desktop/APC-folien.tex";
	
	public static void main(String[] argv)
	{
		CurriculumVitae0 cur = new CurriculumVitae0();
		cur.writeCV(cur.FILEPATH);
	}
	
	
	/**
	 * Convert Umlaut in Latex Umlaut.
	 * 
	 * @param textWithUmlaut the text with umlaut
	 * @return equal text without umlaut.
	 */
	private String convertUmlaut(String textWithUmlaut)
	{
		StringBuilder textWithConvertUmlaut = new StringBuilder();
		char[] tempTextWithUmlaut = textWithUmlaut.toLowerCase().toCharArray();
		for (char letter : tempTextWithUmlaut) 
		{
			switch (letter)
			{
			case 'ä':
			case 'ö':
			case 'ü':
				textWithConvertUmlaut.append("\\\"");
				textWithConvertUmlaut.append(letter);
				break;
			case 'ß':
				textWithConvertUmlaut.append("\\ss ");
				break;
				
			default:
				textWithConvertUmlaut.append(letter);
			}
		}
		
		return textWithConvertUmlaut.toString();
	}

	/**
	 * Create a string wtih personaldata and give it back.
	 * 
	 * @param givenName
	 * @param lastName
	 * @param picturePath
	 * @return a formatted text, wich latex can read.
	 */
	private String createPersonalData(String givenName, String lastName, String picturePath)
	{
		try
		{
			// Check given data
			if (givenName == "" || lastName == "")
				throw new Exception("MissingName");
		}catch (Exception ex)
		{
			System.out.println("Error: " + ex.getMessage());
			this.printErrorToLogFile("Error: " + ex.getMessage());
		}
		
		StringBuilder personalData = new StringBuilder();
		// Create GivenName
		personalData.append("\\firstname{");
		personalData.append(givenName);
		personalData.append("}");
		personalData.append(System.getProperty("line.separator"));
		
		// Create LastName
		personalData.append("\\familyname{");
		personalData.append(lastName);
		personalData.append("}");
		personalData.append(System.getProperty("line.separator"));

		File tempPictureFile = new File(picturePath);
		if (!tempPictureFile.exists())
		{
			// Create PicturePath 
			personalData.append("\\photo [96 pt ]{");
			personalData.append(picturePath);
			personalData.append("}");
			personalData.append(System.getProperty("line.separator"));
		}
		
		return personalData.toString();
	}

	
	/**
	 * Create a mobileline in latex format.
	 * 
	 * @param mobileNumber
	 * @return the formatted mobileLine.
	 */
	private String createMobileLine(String mobileNumber)
	{
		try
		{
			// Check given string
			if (!mobileNumber.matches(REGEXGERMANPHONENUMBER))
				throw new Exception("InvalidMobileNumber");
		}
		catch (Exception ex)
		{
			System.out.println("Error: " + ex.getMessage());
			this.printErrorToLogFile("Error: " + ex.getMessage());
		}
		
		return this.createCVLine("\\mobilesymbol", mobileNumber);
	}

	/**
	 * Create a emailline in latex format.
	 * 
	 * @param emailLine
	 * @return the formatted emailline.
	 */
	private String createEmailLine(String emailLine)
	{	
		try
		{
			// Check given string
			if (!emailLine.matches(REGEXEMAIL))
				throw new Exception("InvalidEmail");
		}
		catch (Exception ex)
		{
			System.out.println("Error: " + ex.getMessage());
			this.printErrorToLogFile("Error: " + ex.getMessage());
		}
		
		return this.createCVLine("\\emailsymbol", "\\href{mailto :" + emailLine + "}{" + emailLine +"}");
	}

	/**
	 * Create a cvline for latex.
	 * 
	 * @param first 
	 * @param second
	 * @return the cvline
	 */
	private String createCVLine(String first, String second)
	{
		try
		{
			// Check given string
			if (second.equals(""))
				throw new Exception("InvalidCVLine");
		}
		catch (Exception ex)
		{
			System.out.println("Error: " + ex.getMessage());
			this.printErrorToLogFile("Error: " + ex.getMessage());
		}
		
		StringBuilder createCVLineBuilder = new StringBuilder();
		createCVLineBuilder.append("\\cvline{");
		createCVLineBuilder.append(first);
		createCVLineBuilder.append("}{");
		createCVLineBuilder.append(second);
		createCVLineBuilder.append("}");
		createCVLineBuilder.append(System.getProperty("line.separator"));
		
		return  createCVLineBuilder.toString();
	}

	/**
	 * Create a cventry for latex.
	 * 
	 * @param cvEntryArray
	 * @return the cventry
	 */
	private String createCVEntry(String[] cvEntryArray)
	{
		try
		{
			// Check given string
			if (cvEntryArray[0].equals("") || cvEntryArray[1].equals(""))	
				throw new Exception("InvalidCVEntry");
		}
		catch (Exception ex)
		{
			System.out.println("Error: " + ex.getMessage());
			this.printErrorToLogFile("Error: " + ex.getMessage());
		}
		
		StringBuilder createCVEntryBuilder = new StringBuilder();
		createCVEntryBuilder.append("\\cventry{");
		for (int i = 0; i < cvEntryArray.length; i++) 
		{
			createCVEntryBuilder.append(cvEntryArray[i]);
			createCVEntryBuilder.append("}{");
		}
		createCVEntryBuilder.append("}");
		createCVEntryBuilder.append(System.getProperty("line.separator"));
		
		
		return createCVEntryBuilder.toString();
	}

	/**
	 * Create a tex File
	 * 
	 * @param fullFilePath Path to tex File
	 */
	private void writeCV(String fullFilePath)
	{
		File tempFile = new File(fullFilePath);
		Scanner sc = new Scanner(System.in);
		
		try
		{
			// Check if File exist
			if (!tempFile.exists())
				throw new FileNotFoundException("File does not exist!");
			
			// Check if extension equls .tex
			if (!tempFile.getAbsolutePath().endsWith(".tex"))
				throw new Exception("File does not ends with .tex");
				
			// Check if file is writable
			if (!tempFile.canWrite())
				throw new Exception("File is read-only!");
		}
		catch (Exception ex)
		{
			System.out.println("Error: " + ex.getMessage());
			this.printErrorToLogFile("Error: " + ex.getMessage());
		}
		
		StringBuilder texFile = new StringBuilder();
		texFile.append("%use class moderncv");
		texFile.append(System.getProperty("line.separator"));
		texFile.append("\\documentclass [11pt, a4paper] { moderncv }");
		texFile.append(System.getProperty("line.separator"));
		texFile.append("%language package");
		texFile.append(System.getProperty("line.separator"));
		texFile.append("\\usepackage [ german ]{ babel }");
		texFile.append(System.getProperty("line.separator"));
		texFile.append("%choosen theme");
		texFile.append(System.getProperty("line.separator"));
		texFile.append("\\moderncvtheme [ blue ]{ classic }");
		texFile.append(System.getProperty("line.separator"));
		
		
		String givenName, lastName, picturePath, mobileNumber, emailLine;
		System.out.print("Bitte den Vornamen eingeben: ");
		givenName = this.convertUmlaut(sc.nextLine());
		System.out.print("Bitte den Nachnamen eingeben: ");
		lastName = this.convertUmlaut(sc.nextLine());
		System.out.print("Bitte den vollständigen Pfad zu dem Bild eingeben: ");
		picturePath = this.convertUmlaut(sc.nextLine());
		System.out.print("Bitte eine deutsche Mobilfunktnummer eingeben: ");
		mobileNumber = this.convertUmlaut(sc.nextLine());
		System.out.print("Bitte eine e-Mail eingeben: ");
		emailLine = this.convertUmlaut(sc.nextLine());
		
		texFile.append(this.createPersonalData(givenName, lastName, picturePath));
		texFile.append("%create a document");
		texFile.append(System.getProperty("line.separator"));
		texFile.append("\\begin{document}");
		texFile.append(System.getProperty("line.separator"));
		texFile.append(System.getProperty("line.separator"));
		
		texFile.append("%create title based on personal data");
		texFile.append(System.getProperty("line.separator"));
		texFile.append("\\maketitle");
		texFile.append(System.getProperty("line.separator"));
		texFile.append(System.getProperty("line.separator"));
		
		// Section contact data
		texFile.append(this.createNewSection(this.convertUmlaut("Kontaktdaten"), "section for contact data"));
		texFile.append(this.createCVLine("", "Sesamstra\\ss e"));
		texFile.append(this.createCVLine("", "12345 EIS"));
		texFile.append(this.createMobileLine(mobileNumber));
		texFile.append(this.createEmailLine(emailLine));
		
		// section education
		texFile.append(this.createNewSection(this.convertUmlaut("Ausbildung"), "section for education"));
		texFile.append(this.createCVEntry(new String[] 
				{ "10/2012 − heute", "Studium der Informatik", "Johannes Gutenberg−Universit\\”at Mainz", "", "", "" }));
		texFile.append(this.createCVEntry(new String[] 
				{ "10/2005 − 5/2012", "Abitur", "Muppet−Gymnasium", "Note : 1,3", "", "" }));
		
		// section language
		texFile.append(this.createNewSection(this.convertUmlaut("Sprachen"), "section for language"));
		texFile.append(this.createCVLine("Deutsch", "Muttersprache"));
		texFile.append(this.createCVLine("English", this.convertUmlaut("fließend in Wort und Schrift")));
		
		texFile.append(System.getProperty("line.separator"));
		texFile.append("\\end{document}");
		texFile.append(System.getProperty("line.separator"));
		
		try
		{
			// Check if File exist
			if (!tempFile.exists())
				throw new FileNotFoundException("File does not exist!");
			
			RandomAccessFile raf = new RandomAccessFile(FILEPATH, "rw");
			raf.seek(raf.length());
			raf.write(texFile.toString().getBytes());
			raf.write(System.getProperty("line.separator").getBytes());
			raf.close();
		}
		catch (Exception ex)
		{
			System.out.println("Error: " + ex.getMessage());
			return;
		}
		
		System.out.println("Das File ist erstellt.");
	}
	
	private String createNewSection(String sectionName, String comment)
	{
		StringBuilder section = new  StringBuilder();
		section.append(System.getProperty("line.separator"));
		section.append("%" + comment);
		section.append(System.getProperty("line.separator"));
		section.append("\\section{"+sectionName+"}");
		section.append(System.getProperty("line.separator"));
		return section.toString();
	}
	
	private void printErrorToLogFile(String errorMessage)
	{
		File tempFile = new File(FILEPATH);
		
		try
		{
			// Check if File exist
			if (!tempFile.exists())
				throw new FileNotFoundException("File does not exist!");
			
			RandomAccessFile raf = new RandomAccessFile(FILEPATH, "rw");
			raf.seek(raf.length());
			raf.write(errorMessage.getBytes());
			raf.write(System.getProperty("line.separator").getBytes());
			raf.close();
			
			System.exit(0);
		}
		catch (Exception ex)
		{
			System.out.println("Error: " + ex.getMessage());
			return;
		}
	}
}
